/**
 * └── 菜单1：时间
 *     └── 子菜单1：调节
 *     └── 子菜单2：同步
 * └── 菜单2：日期
 *     └── 子菜单1：调节
 *     └── 子菜单2：同步
 * └── 菜单3：温度
 *     └── 子菜单2：同步
 * └── 菜单4：图标
 *     └── 子菜单1：切换
 * └── 菜单5：IP
 * └── 菜单6：设置
 *     └── 子菜单1：亮度调节
 *     └── 子菜单2：系统更新
 * 
 * 逻辑：
 * 定时器：idle情况下自动切换
 * loop：循环显示函数+摁键判断，判断进入下级（加入判断，如果flag_loop为1，传入显示函数为。。。）
 * main_menu循环：改变控制显示flag_main_menu，判断摁键（下级循环以此类推）
 * 
 * 关于WiFi下获取json逻辑：
 * 1. 获取main.json，得到各个部分图标，如clonk，setting，setting_light等等的获取地址，赋值到本地变量，如果无法下载，切换本地数组
 * 2. 获取各个部分的数组文件赋值到本地变量中，后续步骤可以考虑不用联网下载了
 * 
 * 
 * * * * * * * * * * * * * * * * * * 
 * 版本记录
 * 1. V003：首次更新版本
 * 2. V004：增加强制更新：MUST_update，修改无法自动升级Bug
 * 2. V005：添加idle图标，删除日历边框
 * 
 * */

#include <ESP8266WiFi.h>
#include <ArduinoOTA.h>
#include <Adafruit_NeoPixel.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <NTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <Ticker.h>
#include <ESP8266httpUpdate.h>
#include <TFT_eSPI.h>

#define PIN D7
#define LED_WIDTH 10
#define LED_HEIGHT 10

/**
 * DEBUG = 0   //不开启debug模式
 * DEBUG = 1   //开启debug模式
 * */
#define DEBUG 0  //DEBUG模式

/**
 * X.Y.Z[主版本号.次版本号.修订号]
 * */
#define APP_VERSION "beta_0_0_5"  // app version
uint8_t app_version_X = 0;        //OTA 版本号
uint8_t app_version_Y = 0;        //OTA 版本号
uint8_t app_version_Z = 5;        //OTA 版本号

uint8_t menu_idle_flag = 0;         //menu_idle菜单flag
uint8_t menu_idle_ticker_flag = 1;  //menu_idle菜单定时变化flag到25为5s变换
uint8_t menu_main_ticker_flag = 1;  //其他菜单flag到25为5s返回menu_idle
uint8_t menu_main_flag = 1;         //所有菜单（除了idle）flag
uint8_t icon_pic_gif_flag = 1;      //图标动态值1~3
uint8_t icon_pic_gif = 1;           //图标动态值1~3
uint8_t OTA_flag = 0;               //OTA 定时更新

uint8_t calendar_day = 1;     //日期存储
uint8_t calendar_month = 1;   //月份存储
uint8_t calendar_year = 1;    //年份存储
uint8_t calendar_hour = 1;    //小时存储
uint8_t calendar_minute = 1;  //分钟存储
uint8_t calendar_second = 1;  //秒存储

int mpu6050_x = 0;
int mpu6050_y = 0;
int mpu6050_z = 0;

uint8_t button_time = 0;
// int what_menu = 1;
uint8_t brightness = 10;  // 亮度1～100

// IP 存储变量
String ESP_IP = "";
String targetIP = "";
String response;
String sysTime1;

// htmlPage用到的变量需要先定义
#include "htmlPage.h"
#include "ICON.h"
// 参考网址：https://developer.lametric.com/icons

uint8_t led_r = 0;
uint8_t led_g = 0;
uint8_t led_b = 0;
String menu_layout;
/*
校准时区 由于全球的时间是不同的，所以需要校准时间，以北京时间为例，在创建实例的时候，见校准参数传入即可，具体操作如下： NTPClient
timeClient(ntpUDP, “ntp1.aliyun.com”,60608, 30601000);
*/
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);


unsigned int localUdpPort = 4210;                      // local port to listen on
char incomingPacket[255];                              // buffer for incoming packets
char replyPacket[] = "Hi there! Got the message :-)";  // a reply string to send back
char* forecast_item_type = "今日天气";
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(100, PIN, NEO_GRB + NEO_KHZ800);

// 创建WiFiClient对象
WiFiClientSecure client;
// 创建HTTPClient对象并设置WiFiClient
HTTPClient http;
// ESP8266HTTPUpdateServer httpUpdater;
WiFiClient UpdateClient;

// 闪烁时间间隔(秒)
const int blinkInterval = 10;
const long interval = 1000;

// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = "TP-LINK_8888";
const char* password = "13798409004";

const char* ssid_1 = "kirisun-guest";
const char* password_1 = "www.kirisun.com";

const char* ssid_2 = "TP-LINK_20B2";
const char* password_2 = "12345678";

const char* ssid_3 = "DN39";
const char* password_3 = "12345678";

unsigned int localPort = 4210;

// WiFiServer server(80);  //创建tcp server
ESP8266WebServer esp8266_server(80);
Ticker ticker;
// Ticker OTATicker;
Adafruit_MPU6050 mpu;

// 在Tinker对象控制下，此函数将会定时执行。
/**
 * 功能：Tinker 定时调用函数0.2s一次，定时器
 * @param NONE
 * @return NONE
 * @example tickerCount();
 * @note NONE
 * @history
 * V0.0.1 2024-01-06 初始版本
 * */
void tickerCount() {
  // 获取陀螺仪

#if DEBUG == 1

  // 这里是debug模式下的代码
  Serial.printf("debug模式");
  
#endif

#if DEBUG == 0

  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);
  mpu6050_x = a.acceleration.x;
  mpu6050_y = a.acceleration.y;
  mpu6050_z = a.acceleration.z;
  
#endif

  // flag++
  menu_main_ticker_flag++;
  menu_idle_ticker_flag++;
  icon_pic_gif_flag++;
  if (icon_pic_gif_flag >= 2) {
    icon_pic_gif_flag = 0;
    icon_pic_gif++;
    if (icon_pic_gif >= 5) {
      icon_pic_gif = 0;
    }
  }

  // testlight();
  if (READ_GPIO() != "0" || abs(mpu6050_y) > 5) {
    menu_main_ticker_flag = 0;
  }
}

/**
 * 功能：Tinker 定时调用函数60s一次
 * @param NONE
 * @return NONE
 * @example OTA_Check();
 * @note NONE
 * @history
 * V0.0.1 2024-01-06 初始版本
 * */
void OTA_Check() {
  OTA_flag = 1;
}


/**
 * 功能：OTA初始化
 * @param NONE
 * @return NONE
 * @example arduino_8266_OTA();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void arduino_8266_OTA() {
  // OTA设置并启动
  // ArduinoOTA.setHostname("ESP8266");
  // ArduinoOTA.setPassword("12345678");
  ArduinoOTA.begin();
  // //注释打印 Serial.printf("\nAPP version: %s\r\n", APP_VERSION);
  //注释打印 Serial.printf("\nAPP version: V%d.%d.%d\r\n", app_version_X, app_version_Y, app_version_Z);
  //注释打印 Serial.println("OTA ready");
  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else {  // U_FS
      type = "filesystem";
    }
    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    //注释打印 Serial.println("Start updating " + type);
    RGB_GFX_PIC(up_date);
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    //注释打印 Serial.printf("Progress: %u%%\r", (progress / (total / 100)));

    // strip.setPixelColor((progress / (total / 100)) - 1, 1, 0, 1);
    strip.setPixelColor(((progress / (total / 100))) - 1, (progress / (total / 100)) / 100 * 255 * brightness / 100, (255 - (progress / (total / 100)) / 100 * 255) * brightness / 100, (255 - (progress / (total / 100)) / 100 * 255) * brightness / 100);
    strip.show();
  });
  ArduinoOTA.onError([](ota_error_t error) {
    //注释打印 Serial.printf("OTA更新发生错误[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      //注释打印 Serial.println("认证失败");
    } else if (error == OTA_BEGIN_ERROR) {
      //注释打印 Serial.println("开始失败");
    } else if (error == OTA_CONNECT_ERROR) {
      //注释打印 Serial.println("连接失败");
    } else if (error == OTA_RECEIVE_ERROR) {
      //注释打印 Serial.println("接收失败");
    } else if (error == OTA_END_ERROR) {
      //注释打印 Serial.println("结束失败");
    }
    // 复位设备
    ESP.restart();
  });
  ArduinoOTA.onEnd([]() {
    //注释打印 Serial.println("OTA更新结束");
    strip.clear();  // 关闭所有灯
  });
}

/**
 * 功能：Wifi连接
 * @param NONE
 * @return NONE
 * @example connectWifi();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void connectWifi() {
  // 开始连接wifi
  WiFi.begin(ssid, password);
  int num = 0;
  // 等待WiFi连接,连接成功打印IP
  while (WiFi.status() != WL_CONNECTED) {
    //注释打印 Serial.print(".");
    RGB_GFX_PIC(wifi_connect_1);
    delay(500);
    //注释打印 Serial.print(".");
    RGB_GFX_PIC(wifi_connect_2);
    delay(500);
    //注释打印 Serial.print(".");
    RGB_GFX_PIC(wifi_connect_3);
    delay(500);
    num = num + 1;
    if (num > 9) {
      break;
    }
    strip.clear();  // 关闭所有灯
  }

  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || (WiFi.status() != WL_CONNECTED)) {
    RGB_GFX_PIC(wifi_connect_error);
    strip.show();
  }
  delay(300);

  //WIFI2.1
  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid_1, password_1);
    num = 0;
    // 等待WiFi连接,连接成功打印IP
    while (WiFi.status() != WL_CONNECTED) {
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_1);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_2);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_3);
      delay(500);
      num = num + 1;
      if (num > 9) {
        break;
      }
      strip.clear();  // 关闭所有灯
    }
  }
  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || WiFi.status() != WL_CONNECTED) {
    RGB_GFX_PIC(wifi_connect_error);
    strip.show();
  }
  delay(300);

  //WIFI2
  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid_2, password_2);
    num = 0;
    // 等待WiFi连接,连接成功打印IP
    while (WiFi.status() != WL_CONNECTED) {
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_1);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_2);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_3);
      delay(500);
      num = num + 1;
      if (num > 9) {
        break;
      }
      strip.clear();  // 关闭所有灯
    }
  }
  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || WiFi.status() != WL_CONNECTED) {
    RGB_GFX_PIC(wifi_connect_error);
    strip.show();
  }
  delay(300);

  //WIFI3
  if (HTTP_request_EZ("http://quan.suning.com/getSysTime.do") == "0" || WiFi.status() != WL_CONNECTED) {
    WiFi.begin(ssid_3, password_3);
    num = 0;
    // 等待WiFi连接,连接成功打印IP
    while (WiFi.status() != WL_CONNECTED) {
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_1);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_2);
      delay(500);
      //注释打印 Serial.print(".");
      RGB_GFX_PIC(wifi_connect_3);
      delay(500);
      num = num + 1;
      if (num > 9) {
        break;
      }
      strip.clear();  // 关闭所有灯
    }
  }


  //注释打印 Serial.println("");
  //注释打印 Serial.println("WiFi Connected!");
  //注释打印 Serial.print("IP address:\t");
  //注释打印 Serial.println(WiFi.localIP());
  // ESP_IP = WiFi.localIP().toString();
  strip.show();

  if (WiFi.status() != WL_CONNECTED) {
    connectsoftAP();  // 无法连接 WiFi 打开 AP 模式
    RGB_GFX_PIC(wifi_connect_error);
    strip.show();
  } else {
    strip.clear();  // 关闭所有灯
    RGB_GFX_PIC(right_icon);
  }
}

/**
 * 功能：AP连接
 * @param NONE
 * @return NONE
 * @example connectsoftAP();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void connectsoftAP() {
  // 设置内网
  IPAddress softLocal(192, 168, 128, 1);  // 1 设置内网WIFI IP地址
  IPAddress softGateway(192, 168, 128, 1);
  IPAddress softSubnet(255, 255, 255, 0);
  WiFi.softAPConfig(softLocal, softGateway, softSubnet);
  String apName = ("ESP8266_" + (String)ESP.getChipId());  // 2 设置WIFI名称
  const char* softAPName = apName.c_str();
  WiFi.softAP(softAPName, "adminadmin");  // 3创建wifi  名称 +密码 adminadmin  IPAddress myIP = WiFi.softAPIP();  // 4输出创建的WIFI IP地址
  //注释打印 Serial.print("AP IP address: ");
  //注释打印 Serial.println(WiFi.localIP());
  // ESP_IP = WiFi.localIP().toString();
  //注释打印 Serial.print("softAPName: ");  // 5输出WIFI 名称
  //注释打印 Serial.println(apName);
}

/*设置服务器根目录即'/'的函数'handleRoot'
  该函数的作用是每当有客户端访问NodeMCU服务器根目录时，
  NodeMCU都会向访问设备发送 HTTP 状态 200 (Ok) 这是send函数的第一个参数。
  同时NodeMCU还会向浏览器发送HTML代码，以下示例中send函数中第三个参数，
  也就是双引号中的内容就是NodeMCU发送的HTML代码。该代码可在网页中产生LED控制按钮。
  当用户按下按钮时，浏览器将会向NodeMCU的/LED页面发送HTTP请求，请求方式为POST。
  NodeMCU接收到此请求后将会执行handleLED函数内容*/
/*
void handleRoot() {
  esp8266_server.send(200, "text/html", "<form action=\"/LED\" method=\"POST\"><input type=\"submit\" value=\"LED\"></form>");
}
*/

/**
 * 功能：读取头文件html
 * @param NONE
 * @return NONE
 * @example handleRoot();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleRoot() {
  esp8266_server.send(200, "text/html", reload_html());
}

/**
 * 功能：网页控制函数LED
 * @param NONE
 * @return NONE
 * @example handleLED();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleLED() {
  if (esp8266_server.method() == HTTP_POST) {
    String message = esp8266_server.arg("LED");
    if (message == "ON") {
      strip.setPixelColor(6, 0 * brightness / 100, 255 * brightness / 100, 0 * brightness / 100);
      strip.show();
      // 在这里执行打开 LED 的操作
    } else if (message == "OFF") {
      // 在这里执行关闭 LED 的操作
      strip.setPixelColor(6, 0 * brightness / 100, 0 * brightness / 100, 0 * brightness / 100);
      strip.show();
    }
  }
  // 发送响应
  //  esp8266_server.send(200, "text/plain", "OK");
  esp8266_server.sendHeader("Location", "/");  // 跳转回页面根目录
  esp8266_server.send(303);                    // 发送Http相应代码303 跳转
}

/**
 * 功能：网页取色器控制函数RGB
 * @param NONE
 * @return NONE
 * @example handleLEDRGB();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleLEDRGB() {
  if (esp8266_server.method() == HTTP_POST) {
    String message = esp8266_server.arg("LEDRGB");
    String led_r_string = esp8266_server.arg("led_r");
    String led_g_string = esp8266_server.arg("led_g");
    String led_b_string = esp8266_server.arg("led_b");

    led_r = led_r_string.toInt();
    led_g = led_g_string.toInt();
    led_b = led_b_string.toInt();
    strip.setPixelColor(4, led_r * brightness / 100, led_g * brightness / 100, led_b * brightness / 100);
    strip.show();
  }
  // 发送响应
  //  esp8266_server.send(200, "text/plain", "OK");
  esp8266_server.sendHeader("Location", "/");  // 跳转回页默认根目录
  esp8266_server.send(303);                    // 发送Http相应代码303 跳转
}

/**
 * Function：HTTPS请求封装！
 * @param host：请求域名（String类型）
 * @param url：请求地址（String类型）
 * @param parameter：请求参数(String类型)(默认""")
 * @param fingerprint：服务器证书指纹 (String类型)(默认""")
 * @param Port：请求端口(int类型)(默认：443)
 * @param Receive_cache：接收缓存(int类型)(默认：1024)
 * @return 成功返回请求的内容(String类型) 失败则返回"0"
 * @example HTTPS_request("hp-l.gitee.io", "/IoT/index.json", "", "", 443, 1024)
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
String HTTPS_request(String host, String url, String parameter = "", String fingerprint = "", int Port = 443, int Receive_cache = 1024) {
  WiFiClientSecure HTTPS;  // 建立WiFiClientSecure对象
  if (parameter != "")
    parameter = "?" + parameter;
  String postRequest = (String)("GET ") + url + parameter + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/103.0.5060.53" + "\r\n\r\n";

  if (fingerprint.length() == 0)
    HTTPS.setInsecure();  // 不进行服务器身份认证
  else {
    HTTPS.setFingerprint(fingerprint.c_str());  // 服务器证书指纹进行服务器身份认证
  }
  int cache = sizeof(postRequest) + 10;
  //注释打印 Serial.print("发送缓存：");
  //注释打印 Serial.println(cache);
  HTTPS.setBufferSizes(Receive_cache, cache);  // 接收和发送缓存大小
  HTTPS.setTimeout(15000);                     // 设置等待的最大毫秒数
  //注释打印 Serial.println("初始化参数完毕！\n开始连接服务器==>>>>>");
  if (!HTTPS.connect(host, Port)) {
    delay(100);
    //注释打印 Serial.println();
    //注释打印 Serial.println("服务器连接失败！");
    return "0";
  } else
    //注释打印 Serial.println("服务器连接成功！\r");
    //注释打印 Serial.println("发送请求：\n" + postRequest);
    HTTPS.print(postRequest.c_str());  // 发送HTTP请求

  // 检查服务器响应信息。通过串口监视器输出服务器状态码和响应头信息
  // 从而确定ESP8266已经成功连接服务器
  //注释打印 Serial.println("获取响应信息========>：\r");
  //注释打印 Serial.println("响应头：");
  while (HTTPS.connected()) {
    String line = HTTPS.readStringUntil('\n');
    //注释打印 Serial.println(line);
    if (line == "\r") {
      //注释打印 Serial.println("响应头输出完毕！");  // //注释打印 Serial.println("响应头屏蔽完毕！\r");
      break;
    }
  }

  //注释打印 Serial.println("截取响应体==========>");
  String line;
  while (HTTPS.connected()) {
    if (HTTPS.available()) {
      line += HTTPS.readString();
    }
    delay(10000);
  }

  //注释打印 Serial.println("响应体信息：\n" + line);
  //注释打印 Serial.println("====================================>");
  //注释打印 Serial.println("变量长度：" + String(line.length()));
  //注释打印 Serial.println("变量大小：" + String(sizeof(line)) + "字节");
  //注释打印 Serial.println("====================================>");
  HTTPS.stop();  // 操作结束，断开服务器连接
  delay(500);
  return line;
}

/**
 * Function：HTTP请求封装
 * @param url：请求地址（String类型）
 * @return 成功返回请求的内容(String类型) 失败则返回"0"
 * @example HTTP_request_EZ("http://quan.suning.com/getSysTime.do")
 * @note NONE
 * @history
 * V0.0.1 2024-01-14 初始版本
 * */
String HTTP_request_EZ(String url) {
  http.setTimeout(5000);
  http.begin(UpdateClient, url);
  int httpCode = http.GET();
  if (httpCode > 0) {
    //注释打印 Serial.printf("[HTTP] GET... code: %d\n", httpCode);
    if (httpCode == HTTP_CODE_OK) {
      //读取响应内容
      response = http.getString();
      //注释打印 Serial.println(response);
    }
    http.end();
    return response;
  } else {
    return "0";
  }
}

/**
 * 功能：网页读取IP控制函数
 * @param NONE
 * @return NONE
 * @example handleIP();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleIP() {
  String message = esp8266_server.arg("IP");
  if (message == "transmit") {
    ESP_IP = WiFi.localIP().toString();
    //注释打印 Serial.print(ESP_IP);
    /* 测试专用 */
    // Send_UDP();
    http_get_weather_json();
    // //注释打印 Serial.print("\n获取到的页面如下：\n" + HTTPS_request("hp-l.gitee.io", "/IoT/electronic.bin", "", "", 443, 1024));
  }
  // 发送响应
  //  esp8266_server.send(200, "text/plain", "OK");
  esp8266_server.sendHeader("Location", "/");  // 跳转回页面根目录
  esp8266_server.send(303);                    // 发送Http相应代码303 跳转
}

/**
 * 功能：网页输入SSID控制WiFi重连
 * @param NONE
 * @return NONE
 * @example handleSSID();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleSSID() {
  String message = esp8266_server.arg("SSID");
  if (message) {
    ssid = message.c_str();
    // message.toCharArray(ssid, sizeof(ssid));
    // strcpy(message, ssid.c_str());

    //注释打印 Serial.print(ssid);  // 5输出WIFI 名称
    connectWifi();  // 连接 WiFi
    delay(10000);
    // 自动跳转
    //  发送响应
    //   esp8266_server.send(200, "text/plain", "OK");
    //  esp8266_server.sendHeader("Location", "/");  // 跳转回页面根目录
    //  esp8266_server.send(301);                    // 发送Http相应代码303 跳转
    //  delay(5000);
    //  esp8266_server.sendHeader("Location", "http://" + ESP_IP, true);
    //  esp8266_server.send(303);                    // 发送Http相应代码303 跳转
  }
}
/**
 * 功能：设置处理404情况的函数
 * @param NONE
 * @return NONE
 * @example handleNotFound();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void handleNotFound() {
  esp8266_server.send(404, "text/plain", "404: Not found");  // 发送 HTTP 状态 404 (未找到页面) 并向浏览器发送文字 "404: Not found"
}

/**
 * 主循环：初始化+菜单循环
 * @param NONE
 * @return NONE
 * @example loop();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void loop() {
  ArduinoOTA.handle();  // OTA侦测
  esp8266_server.handleClient();
  if (READ_GPIO() != "0" || abs(mpu6050_y) > 5) {
    menu_main();
  }
  idle_menu();
  if (OTA_flag) {
    https_get_json();
    //注释打印 Serial.println("60s");
    OTA_flag = 0;
  }
  if (timeClient.getFormattedTime() == "12:00:00") {
    //注释打印 Serial.println("中午 12 点同步时间");
    http_get_time_json();
  }
  if (timeClient.getMinutes() == 30 && timeClient.getSeconds() == 00) {
    //注释打印 Serial.println("半小时测试更新");
    // https_get_json();
    // OTA_flag = 1;
    OTA_Check();
  }

  // // UDP 侦测
  // int packetSize = ntpUDP.parsePacket();
  // if (packetSize)
  // {
  //   // receive incoming UDP packets
  //   //注释打印 Serial.printf("Received %d bytes from %s, port %d\n", packetSize, ntpUDP.remoteIP().toString().c_str(), ntpUDP.remotePort());
  //   int len = ntpUDP.read(incomingPacket, 255);
  //   if (len > 0)
  //   {
  //     incomingPacket[len] = 0;
  //   }
  //   //注释打印 Serial.printf("UDP packet contents: %s\n", incomingPacket);

  //   // send back a reply, to the IP address and port we got the packet from
  //   ntpUDP.beginPacket(ntpUDP.remoteIP(), ntpUDP.remotePort());
  //   ntpUDP.write(replyPacket);
  //   ntpUDP.endPacket();
  // }


  // //注释打印 Serial.print("timeClient = ");
  // //注释打印 Serial.println(timeClient.getHours());
  // //注释打印 Serial.print("timeClient = ");
  // //注释打印 Serial.println(timeClient.getMinutes());
  // //注释打印 Serial.print("timeClient = ");
  // //注释打印 Serial.println(timeClient.getSeconds());
  // //注释打印 Serial.print("timeClient = ");
  // //注释打印 Serial.println(timeClient.getFormattedTime());
  // https_get_json();
  // if (button_time >= 8) {
  //   // https_OTA();
  // }
  // https_OTA();
  // MP6050_TEST();
  // 读取GPIO电平（开关信息）
  // READ_GPIO();
  // RGB_GFX_PIC();
  // menu_main();
}

/**
 * 主代码：初始化+菜单
 * @param NONE
 * @return NONE
 * @example setup();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void setup() {
  pinMode(5, INPUT_PULLUP);   // right
  pinMode(14, INPUT_PULLUP);  // left
  pinMode(12, INPUT_PULLUP);  // middle
  strip.begin();              // Adafruit_NeoPixel初始化
  strip.clear();              // 关闭所有灯
  Serial.begin(115200);
  //注释打印 Serial.println("");
  // pinMode(LED_BUILTIN, OUTPUT);
  ticker.attach(0.2, tickerCount);  // 设置Ticker对象
  // OTATicker.attach(60*30, OTA_Check);  // 设置Ticker对象
  connectWifi();  // 连接 WiFi
  arduino_8266_OTA();
  // 启动tcp连接
  esp8266_server.begin();                                 // 启动网站服务
  esp8266_server.on("/", HTTP_GET, handleRoot);           // 设置服务器根目录即'/'的函数'handleRoot'
  esp8266_server.on("/LED", HTTP_POST, handleLED);        // 设置处理LED控制请求的函数'handleLED'
  esp8266_server.on("/LEDRGB", HTTP_POST, handleLEDRGB);  // 设置处理LED控制请求的函数'handleLED'
  esp8266_server.on("/IP", HTTP_POST, handleIP);          // 设置处理LED控制请求的函数'handleLED'
  esp8266_server.on("/SSID", HTTP_POST, handleSSID);      // 设置处理LED控制请求的函数'handleLED'
  esp8266_server.onNotFound(handleNotFound);
  // Criar threads concorrentes
  // tarefa1.task(thread1);
  // tarefa2.task(thread2);

  // testlight(255, 0, 0, 0, 255, 0);
  // 陀螺仪测试

#if DEBUG == 1
  // 这里是debug模式下的代码
  Serial.printf("debug模式");
#endif

#if DEBUG == 0
  // MP6050_INIT();
#endif

  // 显示屏初始化
  // TFT_eSPI tft = TFT_eSPI();
  // TFT_eSprite clk = TFT_eSprite(&tft);
  // tft.init(ST7735_BLACK);
  // tft.setRotation(1);

  // tft.fillScreen(TFT_BLACK);
  // tft.fillRect(tft.width() / 2, tft.height() / 2, 50, 50, TFT_RED);

  // delay(5000);

  get_the_time();
}

/**
 * 功能：单个RGB变化测试函数
 * @param NONE
 * @return NONE
 * @example testlight();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void testlight(int start_r, int start_g, int start_b, int target_r, int target_g, int target_b) {
  // 渐变的步长
  int step = 5;
  while (!(start_r == target_r && start_g == target_g && start_b == target_b)) {
    if (start_r > target_r) {
      start_r -= step;
    } else if (start_r < target_r) {
      start_r += step;
    }

    if (start_g > target_g) {
      start_g -= step;
    } else if (start_g < target_g) {
      start_g += step;
    }

    if (start_b > target_b) {
      start_b -= step;
    } else if (start_b < target_b) {
      start_b += step;
    }

    // 设置像素的颜色
    strip.setPixelColor(7, strip.Color(start_r * brightness / 100, start_g * brightness / 100, start_b * brightness / 100));

    // 更新 LED 灯带的显示
    strip.show();

    // 等待一段时间，使颜色渐变可见
    delay(100);
  }
}

/**
 * 功能：抓取时间
 * @param NONE
 * @return NONE
 * @example get_the_time();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void get_the_time() {
  //注释打印 Serial.println("get_time");
  delay(2000);
  // while (!timeClient.update()) {
  timeClient.update();
  // }
  if (!timeClient.update()) {
    timeClient.update();
  }
  //注释打印 Serial.println(timeClient.getEpochTime());  //获取Unix时间戳，NTP返回的原始数据，为1970年1月1日0：00到现在的秒数


  // //注释打印 Serial.println(HTTPS_request_EZ("quan.suning.com", "/getSysTime.do", "", "", 443, 1024));
  // http.setTimeout(5000);
  // //注释打印 Serial.println(HTTP_request_EZ("http://quan.suning.com/getSysTime.do"));
  http_get_time_json();
}

/**
 * 功能：陀螺仪初始化
 * @param NONE
 * @return NONE
 * @example MP6050_INIT();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void MP6050_INIT() {
  // Wire.begin(SDA_PIN, SCL_PIN);  // 初始化自定义I2C接口
  Wire.begin(2, 0);  // 初始化自定义I2C接口
  while (!Serial)
    delay(10);  // will pause Zero, Leonardo, etc until serial console opens

  //注释打印 Serial.println("Adafruit MPU6050 test!");

  // Try to initialize!
  if (!mpu.begin()) {
    //注释打印 Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  //注释打印 Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  //注释打印 Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      //注释打印 Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      //注释打印 Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      //注释打印 Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
      //注释打印 Serial.println("+-16G");
      break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  //注释打印 Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      //注释打印 Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      //注释打印 Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      //注释打印 Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      //注释打印 Serial.println("+- 2000 deg/s");
      break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_5_HZ);
  //注释打印 Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      //注释打印 Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      //注释打印 Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      //注释打印 Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      //注释打印 Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      //注释打印 Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      //注释打印 Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      //注释打印 Serial.println("5 Hz");
      break;
  }

  //注释打印 Serial.println("");
  delay(100);
}

/**
 * 功能：陀螺仪测试
 * @param NONE
 * @return NONE
 * @example MP6050_INIT();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * */
void MP6050_TEST() {
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  //注释打印 Serial.print("Acceleration X: ");
  //注释打印 Serial.print(a.acceleration.x);
  //注释打印 Serial.print(", Y: ");
  //注释打印 Serial.print(a.acceleration.y);
  //注释打印 Serial.print(", Z: ");
  //注释打印 Serial.print(a.acceleration.z);
  //注释打印 Serial.println(" m/s^2");

  // delay(200);
}

/**
 * 功能：开关读取
 * @param NONE
 * @return NONE
 * @example READ_GPIO();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * V0.0.2 2024-01-06 仅 gpio 读取
 * */
String READ_GPIO() {
  // pinMode(5, INPUT_PULLUP);   //right
  // pinMode(14, INPUT_PULLUP);  //left
  // pinMode(12, INPUT_PULLUP);  //middle
  if (!digitalRead(5)) {
    return "L";
  } else if (!digitalRead(14)) {
    return "R";
  } else if (!digitalRead(12)) {
    return "M";
  }
  return "0";
}



/**
 * 功能：idle主菜单函数
 * @param NONE
 * @return NONE
 * @example idle_menu();
 * @note 菜单显示图标均为静态，ICON 页面可能需要特殊处理
 * @history
 * V0.0.1 2024-01-06 初始版本
 * */
void idle_menu() {
  delay(100);
  if (menu_idle_ticker_flag >= 50) {
    menu_idle_ticker_flag = 0;
    menu_idle_flag++;
    if (menu_idle_flag > 5) {
      menu_idle_flag = 1;
    }
  }
  switch (menu_idle_flag) {
    case 1:
      //注释打印 Serial.println("clock");
      RGB_GFX_time();
      // RGB_GFX_PIC(demo);
      break;
    case 2:
      //注释打印 Serial.println("calendar");
      // RGB_GFX_PIC(calendar_1);
      RGB_GFX_calendar();
      break;
    case 3:
      //注释打印 Serial.println("weather");
      if (forecast_item_type == "晴") {
        if (icon_pic_gif == 0) { RGB_GFX_PIC(sunny_1); }
        if (icon_pic_gif == 1) { RGB_GFX_PIC(sunny_2); }
        if (icon_pic_gif == 2) { RGB_GFX_PIC(sunny_3); }
        if (icon_pic_gif == 3) { RGB_GFX_PIC(sunny_4); }
        if (icon_pic_gif == 4) { RGB_GFX_PIC(sunny_5); }
      }
      if (forecast_item_type == "多云") {
        if (icon_pic_gif == 0) { RGB_GFX_PIC(sunny_1); }
        if (icon_pic_gif == 1) { RGB_GFX_PIC(sunny_2); }
        if (icon_pic_gif == 2) { RGB_GFX_PIC(sunny_3); }
        if (icon_pic_gif == 3) { RGB_GFX_PIC(sunny_4); }
        if (icon_pic_gif == 4) { RGB_GFX_PIC(sunny_5); }
      }
      break;
    case 4:
      //注释打印 Serial.println("icon");
      // ICON 显示图标
      if (icon_pic_gif == 0) { RGB_GFX_PIC(heart_ins); }
      if (icon_pic_gif == 1) { RGB_GFX_PIC(heart_ins); }
      if (icon_pic_gif == 2) { RGB_GFX_PIC(heart_ins); }
      if (icon_pic_gif == 3) { RGB_GFX_PIC(heart_ins); }
      if (icon_pic_gif == 4) { RGB_GFX_PIC(heart_ins); }
      // if (icon_pic_gif == 4) { RGB_GFX_PIC(fire_5); }
      break;
    case 5:
      //注释打印 Serial.println("icon");
      // ICON 显示图标
      if (icon_pic_gif == 0) { RGB_GFX_PIC(fire_1); }
      if (icon_pic_gif == 1) { RGB_GFX_PIC(fire_2); }
      if (icon_pic_gif == 2) { RGB_GFX_PIC(fire_3); }
      if (icon_pic_gif == 3) { RGB_GFX_PIC(fire_2); }
      if (icon_pic_gif == 4) { RGB_GFX_PIC(fire_1); }
      // if (icon_pic_gif == 4) { RGB_GFX_PIC(fire_5); }
      break;
    default:
      break;
  }
  // //注释打印 Serial.println("back_main_menu");
}

/**
 * 功能：主菜单函数
 * @param NONE
 * @return NONE
 * @example menu_main();
 * @note 菜单显示图标均为静态，ICON 页面可能需要特殊处理
 * @history
 * V0.0.1 2024-01-06 初始版本
 * */
void menu_main() {
  while (1) {
    //   // ticker.detach();
    //   // //注释打印 Serial.printf("ticker.active:  "); //注释打印 Serial.println(ticker.active());
    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      //注释打印 Serial.println("ok");
      //菜单为6摁下M后做的事
      if (menu_main_flag == 1) {
        //注释打印 Serial.println("clock_setting");
        delay(100);
        clock_setting();
      }
      //菜单为6摁下M后做的事
      if (menu_main_flag == 2) {
        //注释打印 Serial.println("calendar_setting");
        delay(100);
        calendar_setting();
      }
      //菜单为6摁下M后做的事
      if (menu_main_flag == 3) {
        //注释打印 Serial.println("weather_setting");
        delay(100);
        weather_setting();
      }
      //菜单为6摁下M后做的事
      if (menu_main_flag == 4) {
        //注释打印 Serial.println("icon_setting");
        delay(100);
        icon_setting();
      }
      //菜单为6摁下M后做的事
      if (menu_main_flag == 5) {
        //注释打印 Serial.println("IP_setting");
        delay(100);
        IP_setting();
      }
      //菜单为6摁下M后做的事
      if (menu_main_flag == 6) {
        //注释打印 Serial.println("menu_setting");
        delay(100);
        menu_setting();
      }
      // button_time++;
    }
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      //锁住
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }

      menu_main_flag--;
      if (menu_main_flag == 0) {
        menu_main_flag = 6;
      }
      //注释打印 Serial.println("L");
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      //锁住
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }

      menu_main_flag++;
      if (menu_main_flag == 7) {
        menu_main_flag = 1;
      }
      //注释打印 Serial.println("R");
    }

    //显示函数
    switch (menu_main_flag) {
      case 1:
        //注释打印 Serial.println("clock");
        RGB_GFX_PIC(clock_1);
        break;
      case 2:
        //注释打印 Serial.println("calendar");
        RGB_GFX_PIC(calendar_1);
        break;
      case 3:
        //注释打印 Serial.println("weather");
        RGB_GFX_PIC(weather_1);
        break;
      case 4:
        //注释打印 Serial.println("icon");
        RGB_GFX_PIC(birthdaycake_1);
        break;
      case 5:
        //注释打印 Serial.println("IP");
        RGB_GFX_PIC(IP_LOGO);
        break;
      case 6:
        //注释打印 Serial.println("SETTING");
        RGB_GFX_PIC(SETTING_LOGO);
        break;
      default:
        break;
    }
    //自动返回侦测
    if (menu_main_ticker_flag >= 25) {
      break;
    }
    // delay(200);
    //   // button_middle_long();
    //   // ticker.attach(0.2, tickerCount);  // 设置Ticker对象
    //   // //注释打印 Serial.print(menu_main_flag);
  }
  //注释打印 Serial.print("break to idle");
}

/**
 * 功能：联网下载json文件
 * @param NONE
 * @return NONE
 * @example https_get_json();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本，未能实现功能
 * */

void https_get_json() {
  menu_layout = HTTP_request_EZ("http://hp-l.gitee.io/electronic_calendar_main/IoT/index.json");
  // menu_layout = HTTPS_request("hp-l.gitee.io", "/IoT/index.json", "", "", 443, 1024);
  // menu_layout = HTTPS_request("hp-l.gitee.io", "/electronic_calendar_main/IoT/index.json", "", "", 443, 1024);
  const size_t capacity = JSON_OBJECT_SIZE(5) + 120;
  DynamicJsonDocument doc(capacity);
  deserializeJson(doc, menu_layout);
  // String nameStr = doc["version"].as<String>();
  uint8_t app_version_X_JSON = doc["app_version_X"].as<int>();
  uint8_t app_version_Y_JSON = doc["app_version_Y"].as<int>();
  uint8_t app_version_Z_JSON = doc["app_version_Z"].as<int>();
  int numberInt = doc["update"].as<int>();
  int MUST_update = doc["MUST_update"].as<int>();
  // 可更新条件：update = 1 同时版本号大于设备版本号
  // 强制更新标志MUST_update = 1时。

  // //注释打印 Serial.printf("\nAPP version: V%d.%d.%d\r\n", app_version_X_JSON, app_version_Y_JSON, app_version_Z_JSON);
  if ((MUST_update == 1) | ((numberInt == 1) && (app_version_X_JSON > app_version_X) | (app_version_Y_JSON > app_version_Y) | (app_version_Z_JSON > app_version_Z))) {
    // //注释打印 Serial.print("version = ");
    // //注释打印 Serial.println(nameStr);
    //注释打印 Serial.printf("\nNEW APP version: V%d.%d.%d\r\n", app_version_X_JSON, app_version_Y_JSON, app_version_Z_JSON);
    https_OTA();
  } else if ((numberInt == 0) && (app_version_X_JSON > app_version_X) | (app_version_Y_JSON > app_version_Y) | (app_version_Z_JSON > app_version_Z)) {
    //注释打印 Serial.printf("\nNEW APP version: V%d.%d.%d\r\n", app_version_X_JSON, app_version_Y_JSON, app_version_Z_JSON);
    //注释打印 Serial.println("版本已锁，无法跟新");
  } else {
    //注释打印 Serial.println("版本最新，无需跟新");
    delay(1);
  }
}


/**
 * 功能：联网下载天气json文件
 * @param NONE
 * @return NONE
 * @example http_get_weather_json();
 * @note NONE
 * @history
 * V0.0.1 2024-03-14 初始版本，未能实现功能
 * */

void http_get_weather_json() {
  menu_layout = HTTP_request_EZ("http://t.weather.itboy.net/api/weather/city/101280601");
  // Stream& input;

  DynamicJsonDocument doc(6144);

  DeserializationError error = deserializeJson(doc, menu_layout);

  if (error) {
    //注释打印 Serial.print(F("deserializeJson() failed: "));
    //注释打印 Serial.println(error.f_str());
    return;
  }

  const char* message = doc["message"];  // "success感谢又拍云(upyun.com)提供CDN赞助"
  int status = doc["status"];            // 200
  const char* date = doc["date"];        // "20240314"
  const char* time = doc["time"];        // "2024-03-14 12:18:33"

  JsonObject cityInfo = doc["cityInfo"];
  const char* cityInfo_city = cityInfo["city"];              // "北京市"
  const char* cityInfo_citykey = cityInfo["citykey"];        // "101010100"
  const char* cityInfo_parent = cityInfo["parent"];          // "北京"
  const char* cityInfo_updateTime = cityInfo["updateTime"];  // "07:46"

  JsonObject data = doc["data"];
  const char* data_shidu = data["shidu"];      // "37%"
  int data_pm25 = data["pm25"];                // 12
  int data_pm10 = data["pm10"];                // 28
  const char* data_quality = data["quality"];  // "优"
  const char* data_wendu = data["wendu"];      // "2"
  const char* data_ganmao = data["ganmao"];    // "各类人群可自由活动"


  char date_day[3];  // 子字符串 "el" 加上一个终止符 '\0'

  // 复制子字符串
  for (int i = 0; i < 2; ++i) {  // 从索引1开始复制，因为我们想要的是 "el"
    date_day[i] = date[i + 6];
  }
  date_day[2] = '\0';  // 添加字符串结束符

  // 打印子字符串
  // Send_UDP("$");
  // Send_UDP((char*)date_day);
  // Send_UDP("$");

  for (JsonObject data_forecast_item : data["forecast"].as<JsonArray>()) {
    const char* data_forecast_item_date = data_forecast_item["date"];        // "14", "15", "16", "17", "18", "19", ...
    const char* data_forecast_item_high = data_forecast_item["high"];        // "高温 19℃", "高温 20℃", "高温 18℃", "高温 ...
    const char* data_forecast_item_low = data_forecast_item["low"];          // "低温 3℃", "低温 2℃", "低温 6℃", "低温 6℃", ...
    const char* data_forecast_item_ymd = data_forecast_item["ymd"];          // "2024-03-14", "2024-03-15", ...
    const char* data_forecast_item_week = data_forecast_item["week"];        // "星期四", "星期五", "星期六", "星期日", "星期一", ...
    const char* data_forecast_item_sunrise = data_forecast_item["sunrise"];  // "06:25", "06:24", "06:22", ...
    const char* data_forecast_item_sunset = data_forecast_item["sunset"];    // "18:20", "18:21", "18:22", ...
    int data_forecast_item_aqi = data_forecast_item["aqi"];                  // 55, 58, 77, 81, 69, 56, 59, 26, 37, 45, 41, ...
    const char* data_forecast_item_fx = data_forecast_item["fx"];            // "西南风", "东南风", "北风", "北风", "北风", "西北风", ...
    const char* data_forecast_item_fl = data_forecast_item["fl"];            // "2级", "2级", "3级", "3级", "2级", "3级", ...
    const char* data_forecast_item_type = data_forecast_item["type"];        // "晴", "晴", "多云", "多云", "多云", "晴", ...
    const char* data_forecast_item_notice = data_forecast_item["notice"];    // "愿你拥有比阳光明媚的心情", "愿你拥有比阳光明媚的心情", ...
    // Send_UDP((char*)data_forecast_item_date);
    if (date_day[1] == data_forecast_item_date[1]) {
      // Send_UDP((char*)data_forecast_item_high);
      // Send_UDP((char*)data_forecast_item_low);
      // Send_UDP("\n");
      // Send_UDP((char*)data_forecast_item_week);
      // Send_UDP("\n");
      // Send_UDP((char*)data_forecast_item_type);
      forecast_item_type = (char*)data_forecast_item_type;
    }
    // Send_UDP((char*)data_forecast_item_date);
    // Send_UDP("###############");
    // Send_UDP((char*)data_forecast_item_high);
  }

  JsonObject data_yesterday = data["yesterday"];
  const char* data_yesterday_date = data_yesterday["date"];        // "13"
  const char* data_yesterday_high = data_yesterday["high"];        // "高温 19℃"
  const char* data_yesterday_low = data_yesterday["low"];          // "低温 1℃"
  const char* data_yesterday_ymd = data_yesterday["ymd"];          // "2024-03-13"
  const char* data_yesterday_week = data_yesterday["week"];        // "星期三"
  const char* data_yesterday_sunrise = data_yesterday["sunrise"];  // "06:27"
  const char* data_yesterday_sunset = data_yesterday["sunset"];    // "18:19"
  int data_yesterday_aqi = data_yesterday["aqi"];                  // 37
  const char* data_yesterday_fx = data_yesterday["fx"];            // "西风"
  const char* data_yesterday_fl = data_yesterday["fl"];            // "2级"
  const char* data_yesterday_type = data_yesterday["type"];        // "晴"
  const char* data_yesterday_notice = data_yesterday["notice"];    // "愿你拥有比阳光明媚的心情"

  // char* a =  (char*)cityInfo_city;
  // Send_UDP((char*)data_yesterday_high);
  Send_UDP(forecast_item_type);
}

/**
 * 功能：联网下载时间json文件
 * @param NONE
 * @return NONE
 * @example http_get_time_json();
 * @note NONE
 * @history
 * V0.0.1 2024-01-15 初始版本，未能实现功能
 * */

void http_get_time_json() {
  menu_layout = HTTP_request_EZ("http://quan.suning.com/getSysTime.do");
  // menu_layout = HTTPS_request("hp-l.gitee.io", "/IoT/index.json", "", "", 443, 1024);
  // menu_layout = HTTPS_request("hp-l.gitee.io", "/electronic_calendar_main/IoT/index.json", "", "", 443, 1024);
  const size_t capacity = JSON_OBJECT_SIZE(2) + 30;
  DynamicJsonDocument doc(capacity);
  deserializeJson(doc, menu_layout);
  // String nameStr = doc["version"].as<String>();
  // String sysTime2 = doc["sysTime2"].as<String>();
  sysTime1 = doc["sysTime1"].as<String>();
  // //注释打印 Serial.print("sysTime2 = ");
  // //注释打印 Serial.print(sysTime2);
  //注释打印 Serial.print("sysTime1 = ");
  //注释打印 Serial.print(sysTime1);
  //注释打印 Serial.print("\n");

  calendar_year = (uint8_t)atoi(sysTime1.substring(2, 4).c_str());
  calendar_month = (uint8_t)atoi(sysTime1.substring(4, 6).c_str());
  calendar_day = (uint8_t)atoi(sysTime1.substring(6, 8).c_str());
  calendar_hour = (uint8_t)atoi(sysTime1.substring(8, 10).c_str());
  calendar_minute = (uint8_t)atoi(sysTime1.substring(10, 12).c_str());
  calendar_second = (uint8_t)atoi(sysTime1.substring(12, 14).c_str());
}

/**
 * 功能：联网下载固件文件OTA
 * @param NONE
 * @return NONE
 * @example https_OTA();
 * @note NONE
 * @link https://zhuanlan.zhihu.com/p/435855807
 * @history
 * V0.0.1 2024-01-05 初始版本，未能实现功能
 * V0.0.1 2024-01-08 更新变量 UpdateClient，成功升级
 * */
void https_OTA() {
  RGB_GFX_PIC(up_date);
  while (1) {
    // 设置回调函数以获取下载进度
    ESPhttpUpdate.onProgress([](int progress, int total) {
      //注释打印 Serial.printf("Progress: %d%%\n", (progress * 100) / total);
      strip.setPixelColor(((progress / (total / 100))) - 1, (progress / (total / 100)) / 100 * 255 * brightness / 100, (255 - (progress / (total / 100)) / 100 * 255) * brightness / 100, (255 - (progress / (total / 100)) / 100 * 255) * brightness / 100);
      strip.show();
    });

    t_httpUpdate_return ret = ESPhttpUpdate.update(UpdateClient, "http://hp-l.gitee.io/electronic_calendar_main/IoT/electronic_beta.bin");
    // t_httpUpdate_return ESP8266HTTPUpdate::handleUpdate("http://hp-l.gitee.io/electronic_calendar_main/IoT/electronic.bin");
    switch (ret) {
      case HTTP_UPDATE_OK:
        //注释打印 Serial.println("Firmware updated successfully");
        break;
      case HTTP_UPDATE_FAILED:
        //注释打印 Serial.println("Firmware update failed");
        break;
      case HTTP_UPDATE_NO_UPDATES:
        //注释打印 Serial.println("No firmware updates available");
        break;
      default:
        //注释打印 Serial.printf("Firmware update error %d\n", ret);
        break;
    }
  }
}

/**
 * 功能：点亮所有灯，按照数组
 * @param NONE
 * @return NONE
 * @example RGB_GFX_PIC();
 * @note NONE
 * @history
 * V0.0.1 2024-01-05 初始版本
 * V0.0.1 2024-01-08 修改显示模式
 * */
void RGB_GFX_PIC(uint8_t rgb_led_data[LED_HEIGHT][LED_WIDTH][3]) {
  strip.clear();  // 关闭所有灯
  for (uint8_t x = 0; x < LED_HEIGHT; x++) {
    for (uint8_t y = 0; y < LED_WIDTH; y++) {
      // rgb_led_data[0][0];
      // int pixelIndex = y * LED_WIDTH + x;
      strip.setPixelColor((x * LED_WIDTH + y), rgb_led_data[x][y][0] * brightness / 100, rgb_led_data[x][y][1] * brightness / 100, rgb_led_data[x][y][2] * brightness / 100);
      // delay(5);
      // strip.setPixelColor(rgb_led_data[x][y][], 0, 100, 0);
      // pixels.setPixelColor(pixelIndex, color);
    }
  }
  strip.show();
}

/**
 * 功能：显示数字或者字母
 * @param a x偏移量
 * @param b y偏移量
 * @param num[]  0
 * @param rgb_led_R  颜色 R
 * @param rgb_led_G  颜色 G
 * @param rgb_led_B  颜色 B
 * @return NONE
 * @example RGB_GFX_NUM();
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
void RGB_GFX_NUM(uint8_t a, uint8_t b, uint8_t num[15], uint8_t rgb_led_R, uint8_t rgb_led_G, uint8_t rgb_led_B) {

  uint8_t i = 0;
  for (uint8_t x = 0 + b; x < 5 + b; x++) {
    for (uint8_t y = 0 + a; y < 3 + a; y++) {
      // rgb_led_data[0][0];
      // int pixelIndex = y * LED_WIDTH + x;
      strip.setPixelColor((x * LED_WIDTH + y), num[i] * rgb_led_R * brightness / 100, num[i] * rgb_led_G * brightness / 100, num[i] * rgb_led_B * brightness / 100);
      i++;
      // delay(5);
      // strip.setPixelColor(rgb_led_data[x][y][], 0, 100, 0);
      // pixels.setPixelColor(pixelIndex, color);
    }
  }
}
/**
 * 功能：显示数字日历
 * @param NONE
 * @return NONE
 * @example RGB_GFX_calendar();
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
void RGB_GFX_calendar() {
  // calendar_hour
  // calendar_minute
  // calendar_second
  // calendar_day
  strip.clear();  // 关闭所有灯
  // if(calendar_hour == 1){
  // }
  //日历 边框
  // for (uint8_t x = 0 + 1; x < 2 + 1; x++) {
  //   for (uint8_t y = 0 + 1; y < 8 + 1; y++) {
  //     strip.setPixelColor((x * LED_WIDTH + y), 100 * brightness / 100, 0, 0);
  //   }
  // }
  // for (uint8_t x = 0 + 3; x < 6 + 3; x++) {
  //   for (uint8_t y = 0 + 1; y < 8 + 1; y++) {
  //     strip.setPixelColor((x * LED_WIDTH + y), 100 * brightness / 100, 100 * brightness / 100, 100 * brightness / 100);
  //   }
  // }

  RGB_GFX_NUM(5, 3, RGB_GFX_calendar_0X(), 100, 0, 100);
  RGB_GFX_NUM(2, 3, RGB_GFX_calendar_X0(), 0, 100, 0);

  strip.show();
}

/**
 * 功能：返回日期十位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_calendar_X0()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_calendar_X0() {
  // 判断日期十位数字
  switch (calendar_day / 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
    case 3:
      return num_3;
  }
  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}
/**
 * 功能：返回日期个位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_calendar_0X()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_calendar_0X() {
  // 判断日期个位数字
  switch (calendar_day % 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
    case 3:
      return num_3;
    case 4:
      return num_4;
    case 5:
      return num_5;
    case 6:
      return num_6;
    case 7:
      return num_7;
    case 8:
      return num_8;
    case 9:
      return num_9;
  }

  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}

/**
 * 功能：显示数字时钟
 * @param NONE
 * @return NONE
 * @example RGB_GFX_time();
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
void RGB_GFX_time() {
  //   calendar_hour
  // calendar_minute
  // calendar_second
  strip.clear();  // 关闭所有灯
  // if(calendar_hour == 1){

  // }
  RGB_GFX_NUM(0, 0, RGB_GFX_time_hour_X0(), 255, 128, 128);
  RGB_GFX_NUM(4, 0, RGB_GFX_time_hour_0X(), 0, 255, 128);
  RGB_GFX_NUM(3, 5, RGB_GFX_time_minute_X0(), 255, 128, 64);
  RGB_GFX_NUM(7, 5, RGB_GFX_time_minute_0X(), 128, 0, 255);

  strip.show();
}

/**
 * 功能：返回小时十位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_time_hour_X0()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_time_hour_X0() {
  // 判断小时十位
  switch (timeClient.getHours() / 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
  }

  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}


/**
 * 功能：返回小时个位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_time_hour_0X()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_time_hour_0X() {
  //判断小时十位
  switch (timeClient.getHours() % 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
    case 3:
      return num_3;
    case 4:
      return num_4;
    case 5:
      return num_5;
    case 6:
      return num_6;
    case 7:
      return num_7;
    case 8:
      return num_8;
    case 9:
      return num_9;
  }
  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}

/**
 * 功能：返回分钟十位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_time_minute_X0()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_time_minute_X0() {
  //判断分钟十位
  switch (timeClient.getMinutes() / 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
    case 3:
      return num_3;
    case 4:
      return num_4;
    case 5:
      return num_5;
  }
  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}

/**
 * 功能：返回分钟个位数字
 * @param NONE
 * @return NONE
 * @example uint8_t* RGB_GFX_time_minute_0X()
 * @note NONE
 * @history
 * V0.0.1 2024-01-16 初始版本
 * */
uint8_t* RGB_GFX_time_minute_0X() {
  // 判断分钟个位
  switch (timeClient.getMinutes() % 10) {
    case 0:
      return num_0;
    case 1:
      return num_1;
    case 2:
      return num_2;
    case 3:
      return num_3;
    case 4:
      return num_4;
    case 5:
      return num_5;
    case 6:
      return num_6;
    case 7:
      return num_7;
    case 8:
      return num_8;
    case 9:
      return num_9;
  }

  // 如果不满足条件，可以返回其他指针或者采取其他处理方式
  return nullptr;
}


/**
 * 功能：摁键长摁时间侦测
 * @param NONE
 * @return NONE
 * @example button_middle_long();
 * @note NONE
 * @history
 * V0.0.1 2024-01-06 初始版本
 * */
void button_middle_long() {
  // 10 2s 0.2s 执行一次摁键侦测

  if (READ_GPIO() == "0" & button_time >= 2) {
    button_time = 0;
  } else if (READ_GPIO() == "M" & button_time >= 8) {
    //注释打印 Serial.println("2 s time button M");
    // 如果需要 10s 长摁，需要添加判断后归零
    button_time = 0;
    // https_OTA();
  }
}

/**
 * 功能：设置菜单函数
 * @param NONE
 * @return NONE
 * @example menu_setting();
 * @note 设置菜单
 * @history
 * V0.0.1 2024-01-08 初始版本
 * */
void menu_setting() {
  menu_main_flag = 1;
  while (1) {
    //判断是否要摁下ok键
    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      if (menu_main_flag == 3) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("back");
        break;
      }
      if (menu_main_flag == 2) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("update");
        https_OTA();
      }
      if (menu_main_flag == 1) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("light");
        light_setting();
      }
    }
    //判断左右摁键
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }
      menu_main_flag--;
      if (menu_main_flag == 0) {
        menu_main_flag = 3;
      }
      //注释打印 Serial.println("L");
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }
      menu_main_flag++;
      if (menu_main_flag == 4) {
        menu_main_flag = 1;
      }
      //注释打印 Serial.println("R");
    }
    //显示函数
    switch (menu_main_flag) {
      case 1:
        //注释打印 Serial.println("light");
        RGB_GFX_PIC(light);
        break;
      case 2:
        //注释打印 Serial.println("update");
        RGB_GFX_PIC(up_date);
        // https_OTA();
        break;
      case 3:
        //注释打印 Serial.println("back");
        // RGB_GFX_PIC(clock_1);
        break;
      // 更多情况...
      default:
        break;
    }

    if (menu_main_ticker_flag >= 25) {
      break;
    }
  }
}


/**
 * 功能：clock调节函数
 * @param NONE
 * @return NONE
 * @example clock_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-09 初始版本
 * */
void clock_setting() {
  menu_main_flag = 1;
  while (1) {
    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      //判断是否要摁下ok键
      if (menu_main_flag == 3) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("back");
        break;
      }
      if (menu_main_flag == 2) {
        delay(10);
        //菜单为6摁下M后做的事
        Send_UDP("time_sync");
        //注释打印 Serial.println("time_sync");
        get_the_time();
      }
      if (menu_main_flag == 1) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("time_config");
      }
    }
    //判断左右摁键
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }
      menu_main_flag--;
      if (menu_main_flag == 0) {
        menu_main_flag = 3;
      }
      //注释打印 Serial.println("L");
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }
      menu_main_flag++;
      if (menu_main_flag == 4) {
        menu_main_flag = 1;
      }
      //注释打印 Serial.println("R");
    }
    //显示函数
    switch (menu_main_flag) {
      case 1:
        //注释打印 Serial.println("time_config");
        // RGB_GFX_PIC(clock_1);
        break;
      case 2:
        //注释打印 Serial.println("time_sync");
        Send_UDP("time_sync");
        // RGB_GFX_PIC(calendar_1);
        // https_OTA();
        break;
      case 3:
        //注释打印 Serial.println("back");
        // RGB_GFX_PIC(clock_1);
        break;
      // 更多情况...
      default:
        break;
    }
    if (menu_main_ticker_flag >= 25) {
      break;
    }
  }
}


/**
 * 功能：calendar调节函数
 * @param NONE
 * @return NONE
 * @example calendar_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-09 初始版本
 * */
void calendar_setting() {
  while (1) {
    delay(100);
    //判断是否要摁下ok键
    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      //菜单为6摁下M后做的事
      //注释打印 Serial.println("back");
      break;
    }
    //判断左右摁键
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }
      calendar_day--;
      if (calendar_day == 0) {
        calendar_day = 31;
      }
      //注释打印 Serial.println("L");
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }
      calendar_day++;
      if (calendar_day == 32) {
        calendar_day = 1;
      }
      //注释打印 Serial.println("R");
    }
    //显示函数
    /*
    some code
    */
    if (menu_main_ticker_flag >= 25) {
      break;
    }
    RGB_GFX_calendar();
  }
}

/**
 * 功能：icon调节函数
 * @param NONE
 * @return NONE
 * @example icon_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-09 初始版本
 * */
void icon_setting() {
  menu_main_flag = 1;
  while (1) {
    //判断是否要摁下ok键
    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      if (menu_main_flag == 3) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("back");
        break;
      }
      if (menu_main_flag == 2) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("icon1");
      }
      if (menu_main_flag == 1) {
        delay(10);
        //菜单为6摁下M后做的事
        //注释打印 Serial.println("icon2");
      }
    }
    //判断左右摁键
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }
      menu_main_flag--;
      if (menu_main_flag == 0) {
        menu_main_flag = 3;
      }
      //注释打印 Serial.println("L");
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }
      menu_main_flag++;
      if (menu_main_flag == 4) {
        menu_main_flag = 1;
      }
      //注释打印 Serial.println("R");
    }
    //显示函数
    switch (menu_main_flag) {
      case 1:
        //注释打印 Serial.println("icon1");
        // RGB_GFX_PIC(clock_1);
        break;
      case 2:
        //注释打印 Serial.println("icon2");
        // RGB_GFX_PIC(calendar_1);
        // https_OTA();
        break;
      case 3:
        //注释打印 Serial.println("back");
        // RGB_GFX_PIC(clock_1);
        break;
      // 更多情况...
      default:
        break;
    }
    if (menu_main_ticker_flag >= 25) {
      break;
    }
  }
}

/**
 * 功能：weather_setting调节函数
 * @param NONE
 * @return NONE
 * @example weather_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-09 初始版本
 * */
void weather_setting() {
  delay(500);
  //注释打印 Serial.println("sync");
}


/**
 * 功能：IP_setting调节函数
 * @param NONE
 * @return NONE
 * @example IP_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-09 初始版本
 * */
void IP_setting() {
  delay(500);
  //注释打印 Serial.println(WiFi.localIP());
}

/**
 * 功能：亮度调节函数
 * @param NONE
 * @return NONE
 * @example light_setting();
 * @note 
 * @history
 * V0.0.1 2024-01-08 初始版本
 * */
void light_setting() {
  while (1) {
    delay(100);
    // 判断左右摁键
    if (READ_GPIO() == "L" || mpu6050_y < -5) {
      while (READ_GPIO() == "L" || mpu6050_y < -5) {
        delay(100);
      }
      brightness--;
      if (brightness <= 1) {
        brightness = 2;
      }
      //注释打印 Serial.println("L");
      //注释打印 Serial.println(brightness);
    }
    if (READ_GPIO() == "R" || mpu6050_y > 5) {
      while (READ_GPIO() == "R" || mpu6050_y > 5) {
        delay(100);
      }
      brightness++;
      if (brightness >= 100) {
        brightness = 99;
      }
      //注释打印 Serial.println("R");
      //注释打印 Serial.println(brightness);
    }
    //判断左右摁键是否到头

    if (READ_GPIO() == "M" || mpu6050_z < -5) {
      while (READ_GPIO() == "M" || mpu6050_z < -5) {
        delay(100);
      }
      //菜单为6摁下M后做的事
      //注释打印 Serial.println("back");
      break;
    }

    RGB_GFX_PIC(light);
  }
  //注释打印 Serial.println(brightness);
  strip.clear();  // 关闭所有灯
}


/**
 * 功能：UDP发送数据
 * @param NONE
 * @return NONE
 * @example Send_UDP();
 * @note 
 * @history
 * V0.0.1 2024-03-12 初始版本
 * */

void Send_UDP(char* information) {
  ntpUDP.begin(localPort);
  // int n = WiFi.scanNetworks();
  // for (int i = 0; i < n; ++i) {
  //   if (WiFi.SSID(i) == "DN39") {
  //     int rssi = WiFi.RSSI(i);
  //     char chh[5];
  //     itoa(rssi, chh, 10);
  ntpUDP.beginPacket("255.255.255.255", localPort);
  ntpUDP.write(information);
  ntpUDP.endPacket();
  // break;
  //   }
  // }
}
